package com.lz.test

import com.lz.test.exception.APIException
import com.lz.test.pojo.OrderVO
import com.lz.test.pojo.UserDTO
import com.lz.test.pojo.UserVO
import spock.lang.Specification
import spock.lang.Unroll
/**
 * @description ${description}*
 * @date 2021-11-23 11:29
 *
 * @author Lizhong
 */
class UserServiceTest extends Specification {
    def userService = new UserService()
    def userDao = Mock(UserDao)
    def moneyDao = Mock(MoneyDAO)

    void setup() {
        userService.moneyDAO = moneyDao
        userService.userDao = userDao
    }

    @Unroll("车牌")
    def getUserByIdTest() {
        given: "请求参数"
        def user1 = new UserDTO(1, "张三", 18, "男", "上海", "18536821124")
        def user2 = new UserDTO(2, "li", 18, "男", "江苏", "18536821123")
        and:
        userDao.getUserInfo() >> [user1, user2]

        when:
        def response = userService.getUserById(1)
        then: "结果"
        with(response) {
            name == "张三"
            abbreviation == "沪"
            postCode == 200000
        }

    }

    @Unroll("汇率测试")
    def amountExchangeTest() {
        given: "入参"
        def userVo = new UserVO(name: "1", userOrders: [new OrderVO(amount: 1000), new OrderVO(amount: 1000)])
        when:
        userService.setOrderAmountByExchange(userVo);
        then:
        2 * moneyDao.getExchangeByCountry(_) >> 0.9 >> 0.8
        and: "result"
//        where:
//        userId | user || result
//        1 |  new UserVO(name: "1", userOrders: [new OrderVO(amount: 1000), new OrderVO(amount: 1000)]) || user.userOrders[0].amount == 900 && user.userOrders[0].amount == 800
        with(userVo) {
            userOrders[0].amount == 900
            userOrders[1].amount == 800
        }
    }

    @Unroll("当输入的用户id为:#uid 时返回的邮编是:#postCodeResult，处理后的电话号码是:#telephoneResult")
    def mockMethod() {
        given: "mock掉接口返回的用户信息"
        userDao.getUserInfo() >> users

        when: "调用获取用户信息方法"
        def response = userService.getUserById(uid)

        then: "验证返回结果是否符合预期值"
        with(response) {
            postCode == postCodeResult
            telephone == telephoneResult
        }

        where: "表格方式验证用户信息的分支场景"
        uid | users                        || postCodeResult | telephoneResult
        1   | getUser("上海", "13866667777") || 200000         | "138****7777"
        1   | getUser("北京", "13811112222") || 100000         | "138****2222"
        2   | getUser("南京", "13833334444") || 0              | null
    }

    def getUser(String province, String telephone) {
        return [new UserDTO(id: 1, name: "张三", province: province, telephone: telephone)]
    }


    @Unroll
    def "验证用户信息的合法性: #expectedMessage"() {
        when: "调用校验用户方法"
        userService.validateUser(user)

        then: "捕获异常并设置需要验证的异常值"
        def exception = thrown(expectedException)
        exception.errorCode == expectedErrCode
        exception.errorMessage == expectedMessage

        where: "表格方式验证用户信息的合法性"
        user           || expectedException | expectedErrCode | expectedMessage
        getUser(10001) || APIException      | "10001"         | "user is null"
        getUser(10002) || APIException      | "10002"         | "user name is null"
        getUser(10003) || APIException      | "10003"         | "user age is null"
        getUser(10004) || APIException      | "10004"         | "user telephone is null"
        getUser(10005) || APIException      | "10005"         | "user sex is null"
        getUser(10006) || APIException      | "10006"         | "user order is null"
        getUser(10007) || APIException      | "10007"         | "order number is null"
        getUser(10008) || APIException      | "10008"         | "order amount is null"
    }

    def getUser(errCode) {
        def user = new UserVO()
        def condition1 = {
            user.name = "杜兰特"
        }
        def condition2 = {
            user.age = 20
        }
        def condition3 = {
            user.telephone = "15801833812"
        }
        def condition4 = {
            user.sex = "男"
        }
        def condition5 = {
            user.userOrders = [new OrderVO()]
        }
        def condition6 = {
            user.userOrders = [new OrderVO(orderNum: "123456")]
        }

        switch (errCode) {
            case 10001:
                user = null
                break
            case 10002:
                user = new UserVO()
                break
            case 10003:
                condition1()
                break
            case 10004:
                condition1()
                condition2()
                break
            case 10005:
                condition1()
                condition2()
                condition3()
                break
            case 10006:
                condition1()
                condition2()
                condition3()
                condition4()
                break
            case 10007:
                condition1()
                condition2()
                condition3()
                condition4()
                condition5()
                break
            case 10008:
                condition1()
                condition2()
                condition3()
                condition4()
                condition5()
                condition6()
                break
        }
        return user
    }
}
